/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.huawei.spare.part.replace.views.replace.slot;

import animatefx.animation.FadeInDown;
import com.google.common.collect.Lists;
import com.huawei.spare.part.replace.framework.SmartContentPresenter;
import com.huawei.spare.part.replace.framework.SmartDataBus;
import com.huawei.spare.part.replace.framework.SmartRouter;
import com.huawei.spare.part.replace.models.Project;
import com.huawei.spare.part.replace.models.Replacement;
import com.huawei.spare.part.replace.models.Replacement.Slot;
import com.huawei.spare.part.replace.rx.RxUtils;
import com.huawei.spare.part.replace.utils.SSHHelper;
import com.huawei.spare.part.replace.views.widgets.Alerts;
import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.Callable;
import javafx.application.Platform;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.control.ToggleGroup;
import javafx.scene.layout.AnchorPane;
import net.schmizz.sshj.SSHClient;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author Woo
 */
public class SlotPresenter extends SmartContentPresenter {

  private static final Logger log = LoggerFactory.getLogger(SlotPresenter.class);

  @FXML AnchorPane e9000;
  @FXML Label display;

  List<Slot> slots = Lists.newArrayList();
  ToggleGroup selectedSlotToggleGroup = new ToggleGroup();

  @Override
  public void initialize() {
    SmartRouter.get().nextStepButton().setDisable(true);
    final Replacement.SmmAuth auth = SmartDataBus.get().replacement().getSmmAuth();

    //        if (auth.getSmmHost() == null) {
    //            final Configs configs = SmartDataBus.get().getConfigs();
    //            auth.setSmmHost(configs.getDefaultHost());
    //            auth.setSmmUsername(configs.getDefaultUsername());
    //            auth.setSmmPassword(configs.getDefaultPassword());
    //        }

    Platform.runLater(() -> {
      loadSlots(auth);
    });
  }

  private void loadSlots(Replacement.SmmAuth auth) {
    loading("slot.loading.slot", false);
    Observable.defer((Callable<ObservableSource<Boolean>>) () -> {
      List<Integer> failedList = Lists.newArrayList();
      try (SSHClient ssh = SSHHelper.newSSHClient(auth.getSmmHost(), auth.getSmmUsername(), auth.getSmmPassword())) {
        for (int position = 1; position <= 4; position++) { // load slots
          try {
            slots.add(new Slot(position).read(ssh));
          } catch (IOException e) {
            failedList.add(position);
            log.error("Failed to detect slot@" + position, e);
          }
        }
      }
      if (failedList.isEmpty()) {
        return Observable.just(true);
      } else {
        final String join = StringUtils.join(failedList, ",");
        final String message = String.format(getString("slot.load.slot.failed.title"), join);
        return Observable.error(new RuntimeException(message));
      }
    }).compose(RxUtils.loadingTask(this)).subscribe((result) -> {
      renderSlots();
    }, (error) -> {
      Alerts.error("common.title.io.exception", error.getMessage());
      log.warn("Failed to load slot info", error);
    });
  }

  private void renderSlots() {
    slots.forEach((slot) -> {
      SlotItemView itemView = new SlotItemView(slot);
      itemView.getRealPresenter().getSelected().setToggleGroup(selectedSlotToggleGroup);
      e9000.getChildren().add(itemView.getView());
    });

    selectedSlotToggleGroup.selectedToggleProperty().addListener((observable, oldValue, newValue) -> {
      selectedSlotToggleGroup.selectToggle(newValue);
      final Slot selected = (Slot) newValue.getUserData();
      if (selected != null) {
        display.setText(selected.getDisplayMessage());
        if (oldValue == null) {
          new FadeInDown(display).play();
        }

        // 启用下一步按钮
        SmartRouter.get().nextStepButton().setDisable(false);
      }
    });
    // 137 165 195 224 252
    // 28 30 28 28
    // 90 400 height
    //        final URL resource = getClass().getResource(String.format("/assets/e9000/%s.png", model));
    //        Image image = new Image(resource.toExternalForm().toString());
    //        ImageView slot = new ImageView(image);
    //        slot.setFitHeight(SwitchModelHeight);
    //        slot.setFitWidth(SwitchModelWidth);
    ////        AnchorPane.setRightAnchor(slot, E9000SlotStartAt + (index - 1) * SwitchModelWidth);
    //        AnchorPane.setRightAnchor(slot, E9000ModelWidth - slotPosList.get(index - 1));
    //        AnchorPane.setTopAnchor(slot, E9000SlotTopAt);
    //        e9000.getChildren().add(slot);
  }

  @Override
  public Observable<Boolean> onFinish() {
    final Project.Defective defective = SmartDataBus.get().replacement().getProject().getDefective();
    final Slot selectSlot = (Slot) selectedSlotToggleGroup.getSelectedToggle().getUserData();
    final boolean b1 = defective.getBoardType().equalsIgnoreCase(selectSlot.getBoardType());
    final boolean b2 = defective.getSoftwareVersion().equalsIgnoreCase(selectSlot.getSoftwareVersion());
    final String reason = String.format(
        getString("slot.not.match.content"),
        selectSlot.getBoardType(),
        selectSlot.getSoftwareVersion(),
        selectSlot.getCpldVersion(),
        defective.getBoardType(),
        defective.getSoftwareVersion(),
        defective.getCpldVersion()
    );
    //        final boolean b3 = defective.getCpldVersion().equalsIgnoreCase(selectSlot.getCpldVersion());
    if (!selectSlot.isIdentified() || (b1)) {
      if (!b2) {
        Alerts.error("slot.not.match.title", reason);
      }
      SmartDataBus.get().replacement().setSlot(selectSlot);
      return Observable.just(true);
    }

    Alerts.error("slot.not.match.title", reason);
    return Observable.just(false);
  }
}
